package com.zhibang.config.security;

import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


/**
 * Security安全框架 核心配置类
 */
@Configuration
@EnableWebSecurity // 启用security
@EnableMethodSecurity // 启用方法级权限控制
public class SecurityConfig {
    @Resource
    MyUserDetailsService userDetailsService; // 自定义用户认证服务
    @Resource
    SecurityTokenFilter securityTokenFilter; // 自定义token过滤器
    @Resource
    SecurityAuthenticationException securityAuthenticationException; // 自定义认证异常处理器
    @Resource
    SecurityAccessException securityAccessException; // 自定义权限异常处理器
    @Resource
    LogoutSuccessHandler customLogoutSuccessHandler; // 自定义退出成功处理器
    @Resource
    LogoutHandler customLogoutHandler; // 自定义退出处理器


    //  配置过滤器链
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        String[] bai = {
                "/login",
                "/swagger.html",  // swagger页面放行
                "/swagger-ui/**",
                "/ss",
                "/v3/docs"    // swagger json文档数据路径
        };
        //需要登录才能访问的路径
        String[] loginURL={

        };
        // 配置访问控制
        /**
         * antMatchers 匹配指定路径    anyRequest 匹配全部路径
         * authenticated 需要认证   permitAll 不需要认证
         */
        http.authorizeHttpRequests(auth->{
            auth.requestMatchers(bai).permitAll()
                    .requestMatchers(loginURL).authenticated()
                    .anyRequest().permitAll();
        });
        // 禁用session
        http.sessionManagement(sess->{
            sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        });
        // 禁用csrf (跨站请求伪造)
        http.csrf(csrf->csrf.disable());
        // 配置认证过滤器
        http.addFilterBefore(securityTokenFilter, UsernamePasswordAuthenticationFilter.class);
        // 配置认证异常处理器
        http.exceptionHandling(ex->{
            ex.authenticationEntryPoint(securityAuthenticationException);
            ex.accessDeniedHandler(securityAccessException);
        });
        // 配置注销
        http.logout(log->{
            log.logoutUrl("/logout")
                    .logoutSuccessHandler(customLogoutSuccessHandler)
                    .addLogoutHandler(customLogoutHandler);
                });

        // 配置允许跨域
        http.cors(Customizer.withDefaults());
        return http.build();
    }



    @Bean
    public PasswordEncoder passwordEncoder(){
        // 密码加密 随机盐+原密码+SHA-256  散列10次
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager(
            AuthenticationConfiguration config) throws Exception {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder());
        provider.setHideUserNotFoundExceptions(false);

        return new ProviderManager(provider);
    }
}
